package com.qiangqiang.task.server.service;

import com.qiangqiang.task.server.dto.MyRankingDTO;
import com.qiangqiang.task.server.dto.NickNameDTO;
import com.qiangqiang.task.server.dto.UserDTO;
import com.qiangqiang.task.server.entity.UserInfo;
import com.qiangqiang.task.server.enums.UserEnums;
import com.qiangqiang.task.server.exception.UserException;
import com.qiangqiang.task.server.mapper.UserMapper;
import com.qiangqiang.task.server.ranking.entity.RankingUser;
import com.qiangqiang.task.server.util.MathRandom;
import com.qiangqiang.task.server.util.SnowflakeIdWorker;
import com.qiangqiang.task.server.util.TimeFormat;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RankingService rankingService;

    // userId 生成器
    SnowflakeIdWorker userIdWorker = new SnowflakeIdWorker(0, 1);

    public List<UserDTO> getUserList(int page, int pageSize) {
        return userMapper.queryUsers(page, pageSize).
                stream().
                map(e -> {
                    UserDTO userDTO = new UserDTO();
                    BeanUtils.copyProperties(e, userDTO);
                    userDTO.setCreateTime(TimeFormat.converTime(e.getCreateTime()));
                    userDTO.setUpdateTime(TimeFormat.converTime(e.getUpdateTime()));
                    return userDTO;
                }).collect(Collectors.toList());
    }

    public UserDTO getUserById(long userId) {
        UserInfo user = userMapper.queryUserById(userId);
        if (user == null) {
            throw new UserException(UserEnums.USER_NOT_EXIST);
        }
        UserDTO userDTO = new UserDTO();
        BeanUtils.copyProperties(user, userDTO);
        userDTO.setCreateTime(TimeFormat.converTime(user.getCreateTime()));
        userDTO.setUpdateTime(TimeFormat.converTime(user.getUpdateTime()));
        MyRankingDTO rankingDTO = rankingService.getUserRanking(userId);
        userDTO.setAchievement(rankingDTO.getAchievement());
        userDTO.setRanking(rankingDTO.getRanking());
        return userDTO;
    }

    public UserDTO getUserByNickName(String nickName) {
        UserInfo user = userMapper.queryUserByNickName(nickName);
        if (user == null) {
            throw new UserException(UserEnums.USER_NOT_EXIST);
        }
        UserDTO userDTO = new UserDTO();
        BeanUtils.copyProperties(user, userDTO);
        userDTO.setCreateTime(TimeFormat.converTime(user.getCreateTime()));
        userDTO.setUpdateTime(TimeFormat.converTime(user.getUpdateTime()));
        return userDTO;
    }

    public boolean upSertUser(UserInfo user) {
        user.setUserId(userIdWorker.nextId());
        user.setCreateTime(Instant.now().toEpochMilli());
        user.setUpdateTime(Instant.now().toEpochMilli());
        user.setAchievement(MathRandom.percentageRandom());
        RankingUser rankingUser = new RankingUser();
        BeanUtils.copyProperties(user, rankingUser);
        rankingService.insertRankingUser(rankingUser);
        return userMapper.upSertUser(user) > 0;
    }


    public boolean removeUser(long userId) {
        UserInfo user = userMapper.queryUserById(userId);
        if (user == null) {
            throw new UserException(UserEnums.USER_NOT_EXIST);
        }
        return userMapper.deleteUser(userId) > 0;
    }

    public List<String> getNicknamesByIds(List<Long> userIds) {
        List<String> names = userMapper.getNicknamesByIds(userIds);
        if (names == null) {
            throw new UserException(UserEnums.USER_NOT_EXIST);
        }
        return names;
    }

    public List<NickNameDTO> getNickNameDTOByIds(List<Long> userIds) {
        List<NickNameDTO> nameDTOS = userMapper.getNickNameDTOByIds(userIds);
        if (nameDTOS == null) {
            throw new UserException(UserEnums.USER_NOT_EXIST);
        }
        return nameDTOS;
    }
}
